package com.zhuobowen.warehouse.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import com.zhuobowen.common.core.constant.HttpStatus;
import com.zhuobowen.common.excel.utils.ExcelUtil;
import com.zhuobowen.common.log.annotation.Log;
import com.zhuobowen.common.log.enums.BusinessType;
import com.zhuobowen.common.mybatis.core.page.TableDataInfo;
import com.zhuobowen.common.web.core.BaseController;
import com.zhuobowen.warehouse.common.WmsProperties;
import com.zhuobowen.warehouse.domain.vo.ExportImportVo;
import com.zhuobowen.warehouse.domain.vo.ExportOrderVo;
import com.zhuobowen.warehouse.domain.vo.ImportOrderVo;
import com.zhuobowen.warehouse.domain.vo.InventoryVo;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RestController
@RequestMapping("/wms/inventory")
@RequiredArgsConstructor
public class InventoryController extends BaseController {

    private final WmsProperties wmsProperties;

    @GetMapping("/summary/list")
    public TableDataInfo<InventoryVo> summaryList(Integer pageNum, Integer pageSize, String goodsName, String customerName) throws Exception {
        Map<Object, List<Object>> summaryMap = getSummaryMap(pageNum, pageSize, goodsName, customerName);
        List<InventoryVo> list = summaryMap.values().stream()
            .flatMap(item -> {
                Object o = item.get(0);
                JSONObject obj = (JSONObject) o;
                InventoryVo inventoryVo = obj.toBean(InventoryVo.class);
                inventoryVo.setStockCodeCount(item.size());
                return Stream.of(inventoryVo);
            }).collect(Collectors.toList());
        List<InventoryVo> page = ListUtil.page(pageNum - 1, pageSize, list);
        TableDataInfo<InventoryVo> tableDataInfo = new TableDataInfo<>();
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        tableDataInfo.setRows(page);
        tableDataInfo.setTotal(list.size());
        return tableDataInfo;
    }

    @GetMapping("/export-import/list")
    public TableDataInfo<ExportImportVo> exportImportList(Integer pageNum, Integer pageSize, String goodsName, String customerName) throws Exception {
        Map<Object, List<Object>> summaryMap = getSummaryMap(pageNum, pageSize, goodsName, customerName);
        String jsonStr = HttpUtil.createGet(wmsProperties.getRestUrl() + wmsProperties.getInventory().getExportImport())
            .bearerAuth(wmsProperties.getAuthKey())
            .header("Clientid", wmsProperties.getClientId())
            .form(wmsProperties.getPageSizeKey(), pageSize)
            .form(wmsProperties.getPageNumKey(), pageNum)
            .execute()
            .body();
        JSONArray allList = JSONUtil.parseArray(jsonStr);
        List<ExportImportVo> list = allList.toList(ExportImportVo.class).stream()
            .flatMap(exportImportVo -> {
                List<Object> objects = summaryMap.get(exportImportVo.getCustomerID() + "-" + exportImportVo.getName());
                if (CollectionUtil.isNotEmpty(objects)) {
                    exportImportVo.setStockCodeCount(objects.size());
                }
                return Stream.of(exportImportVo);
            }).filter(exportImportVo -> {
                if (goodsName != null &&
                    !StrUtil.contains(exportImportVo.getName(), goodsName)) {
                    return false;
                }
                if (customerName!= null &&
                    !StrUtil.contains(exportImportVo.getCustomerName(), customerName)) {
                    return false;
                }
                return true;
            }).collect(Collectors.toList());
        List<ExportImportVo> page = ListUtil.page(pageNum - 1, pageSize, list);
        TableDataInfo<ExportImportVo> tableDataInfo = new TableDataInfo<>();
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        tableDataInfo.setRows(page);
        tableDataInfo.setTotal(list.size());
        return tableDataInfo;
    }

    @GetMapping("/query/list")
    public TableDataInfo<InventoryVo> queryList(Integer pageNum, Integer pageSize, @RequestParam Map<String, Object> queryMap) throws Exception {
        String jsonStr = HttpUtil.createGet(wmsProperties.getRestUrl() + wmsProperties.getInventory().getQueryPath())
            .bearerAuth(wmsProperties.getAuthKey())
            .header("Clientid", wmsProperties.getClientId())
            .form(queryMap)
            .form(wmsProperties.getPageSizeKey(), pageSize)
            .form(wmsProperties.getPageNumKey(), pageNum)
            .execute()
            .body();
        JSONObject page = JSONUtil.parseObj(jsonStr);
        TableDataInfo<InventoryVo> tableDataInfo = new TableDataInfo<>();
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        tableDataInfo.setRows(page.getJSONArray("items").toList(InventoryVo.class));
        tableDataInfo.setTotal(page.getLong("total"));
        return tableDataInfo;
    }

    @GetMapping("/goods/list")
    public JSONArray goodsList(Integer pageNum, Integer pageSize, @RequestParam Map<String, Object> queryMap) throws Exception {
        String jsonStr = HttpUtil.createGet(wmsProperties.getRestUrl() + wmsProperties.getGoods().getGetSelectItems())
            .bearerAuth(wmsProperties.getAuthKey())
            .header("Clientid", wmsProperties.getClientId())
            .form(queryMap)
            .form(wmsProperties.getPageSizeKey(), pageSize)
            .form(wmsProperties.getPageNumKey(), pageNum)
            .execute()
            .body();
        return JSONUtil.parseArray(jsonStr);
    }

    @GetMapping("/customer/list")
    public JSONArray customerList(Integer pageNum, Integer pageSize, @RequestParam Map<String, Object> queryMap) throws Exception {
        String jsonStr = HttpUtil.createGet(wmsProperties.getRestUrl() + wmsProperties.getCustomer().getGetSelectItems())
            .bearerAuth(wmsProperties.getAuthKey())
            .header("Clientid", wmsProperties.getClientId())
            .form(queryMap)
            .form(wmsProperties.getPageSizeKey(), pageSize)
            .form(wmsProperties.getPageNumKey(), pageNum)
            .execute()
            .body();
        return JSONUtil.parseArray(jsonStr);
    }

    /**
     * 导出库存汇总列表
     */
    @Log(title = "库存汇总", businessType = BusinessType.EXPORT)
    @PostMapping("/summary/export")
    public void export(Integer pageNum, Integer pageSize, String goodsName, String customerName, HttpServletResponse response) {
        Map<Object, List<Object>> summaryMap = getSummaryMap(pageNum, pageSize, goodsName, customerName);
        List<InventoryVo> list = summaryMap.values().stream()
            .flatMap(item -> {
                Object o = item.get(0);
                JSONObject obj = (JSONObject) o;
                InventoryVo inventoryVo = obj.toBean(InventoryVo.class);
                inventoryVo.setStockCodeCount(item.size());
                return Stream.of(inventoryVo);
            }).collect(Collectors.toList());
        ExcelUtil.exportExcel(list.stream().filter(inventoryVo -> {
            if (goodsName != null &&
                !StrUtil.contains(inventoryVo.getGoodsName(), goodsName)) {
                return false;
            }
            if (customerName!= null &&
                !StrUtil.contains(inventoryVo.getCustomerName(), customerName)) {
                return false;
            }
            return true;
        }).collect(Collectors.toList()), "库存汇总", InventoryVo.class, response);
    }

    /**
     * 入库单查询
     */
    @Log(title = "入库单查询")
    @GetMapping("/import-order/list")
    public TableDataInfo<ImportOrderVo> importOrderList(Integer pageNum, Integer pageSize, String customerName, @RequestParam Map<String, Object> queryMap) {
        if (StrUtil.isNotBlank(customerName)) {
            queryMap.remove("pageSize");
            queryMap.remove("pageNum");
        }
        String jsonStr = HttpUtil.createGet(wmsProperties.getRestUrl() + wmsProperties.getImportOrder().getQueryPath())
            .bearerAuth(wmsProperties.getAuthKey())
            .header("Clientid", wmsProperties.getClientId())
            .form(queryMap)
            .form(wmsProperties.getPageSizeKey(), StrUtil.isNotBlank(customerName) ? 99999 : pageSize)
            .form(wmsProperties.getPageNumKey(), StrUtil.isNotBlank(customerName) ? 1 : pageNum)
            .execute()
            .body();
        JSONObject page = JSONUtil.parseObj(jsonStr);
        Long total = page.getLong("total");
        List<ImportOrderVo> items = page.getJSONArray("items").toList(ImportOrderVo.class);
        if (StrUtil.isNotBlank(customerName)) {
            List<ImportOrderVo> collect = items.stream().filter(item ->
                    StrUtil.contains(item.getCustomerName(), customerName))
                .collect(Collectors.toList());
            total = (long) collect.size();
            items = ListUtil.page(pageNum - 1, pageSize, collect);
        }
        TableDataInfo<ImportOrderVo> tableDataInfo = new TableDataInfo<>();
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        tableDataInfo.setRows(items);
        tableDataInfo.setTotal(total);
        return tableDataInfo;
    }

    /**
     * 出库单流水查询
     */
    @Log(title = "出库单流水查询")
    @GetMapping("/export-order/list")
    public TableDataInfo<ExportOrderVo> exportOrderList(Integer pageNum, Integer pageSize, String customerName, @RequestParam Map<String, Object> queryMap) {
        if (StrUtil.isNotBlank(customerName)) {
            queryMap.remove("pageSize");
            queryMap.remove("pageNum");
        }
        String jsonStr = HttpUtil.createGet(wmsProperties.getRestUrl() + wmsProperties.getExportOrder().getQueryPath())
            .bearerAuth(wmsProperties.getAuthKey())
            .header("Clientid", wmsProperties.getClientId())
            .form(queryMap)
            .form(wmsProperties.getPageSizeKey(), StrUtil.isNotBlank(customerName) ? 99999 : pageSize)
            .form(wmsProperties.getPageNumKey(), StrUtil.isNotBlank(customerName) ? 1 : pageNum)
            .execute()
            .body();
        JSONObject page = JSONUtil.parseObj(jsonStr);
        Long total = page.getLong("total");
        List<ExportOrderVo> items = page.getJSONArray("items").toList(ExportOrderVo.class);
        if (StrUtil.isNotBlank(customerName)) {
            List<ExportOrderVo> collect = items.stream().filter(item ->
                    StrUtil.contains(item.getCustomerName(), customerName))
                .collect(Collectors.toList());
            total = (long) collect.size();
            items = ListUtil.page(pageNum - 1, pageSize, collect);
        }
        TableDataInfo<ExportOrderVo> tableDataInfo = new TableDataInfo<>();
        tableDataInfo.setCode(HttpStatus.SUCCESS);
        tableDataInfo.setMsg("查询成功");
        tableDataInfo.setRows(items);
        tableDataInfo.setTotal(total);
        return tableDataInfo;
    }

    /**
     * 导出出入库统计列表
     */
    @Log(title = "出入库统计", businessType = BusinessType.EXPORT)
    @PostMapping("/export-import/export")
    public void exportImportExport(Integer pageNum, Integer pageSize, String goodsName, String customerName, HttpServletResponse response) {
        Map<Object, List<Object>> summaryMap = getSummaryMap(pageNum, pageSize, goodsName, customerName);
        String jsonStr = HttpUtil.createGet(wmsProperties.getRestUrl() + wmsProperties.getInventory().getExportImport())
            .bearerAuth(wmsProperties.getAuthKey())
            .header("Clientid", wmsProperties.getClientId())
            .form(wmsProperties.getPageSizeKey(), pageSize)
            .form(wmsProperties.getPageNumKey(), pageNum)
            .execute()
            .body();
        JSONArray allList = JSONUtil.parseArray(jsonStr);
        List<ExportImportVo> list = allList.toList(ExportImportVo.class).stream()
            .flatMap(exportImportVo -> {
                List<Object> objects = summaryMap.get(exportImportVo.getCustomerID() + "-" + exportImportVo.getName());
                if (CollectionUtil.isNotEmpty(objects)) {
                    exportImportVo.setStockCodeCount(objects.size());
                }
                return Stream.of(exportImportVo);
            }).filter(exportImportVo -> {
                if (goodsName != null &&
                    !StrUtil.contains(exportImportVo.getName(), goodsName)) {
                    return false;
                }
                if (customerName!= null &&
                    !StrUtil.contains(exportImportVo.getCustomerName(), customerName)) {
                    return false;
                }
                return true;
            }).collect(Collectors.toList());
        ExcelUtil.exportExcel(list, "库存汇总", ExportImportVo.class, response);
    }

    private Map<Object, List<Object>> getSummaryMap(Integer pageNum, Integer pageSize, String goodsName, String customerName) {
        String jsonStr = HttpUtil.createGet(wmsProperties.getRestUrl() + wmsProperties.getInventory().getSummaryPath())
            .bearerAuth(wmsProperties.getAuthKey())
            .header("Clientid", wmsProperties.getClientId())
            .form(wmsProperties.getPageSizeKey(), pageSize)
            .form(wmsProperties.getPageNumKey(), pageNum)
            .execute()
            .body();
        JSONArray allList = JSONUtil.parseArray(jsonStr);
        return allList.stream().filter(item -> {
            JSONObject obj = (JSONObject) item;
            InventoryVo inventoryVo = obj.toBean(InventoryVo.class);
            if (goodsName != null &&
                !StrUtil.contains(inventoryVo.getGoodsName(), goodsName)) {
                return false;
            }
            if (customerName!= null &&
                !StrUtil.contains(inventoryVo.getCustomerName(), customerName)) {
                return false;
            }
            return true;
        }).collect(Collectors.groupingBy(item -> {
            JSONObject obj = (JSONObject) item;
            InventoryVo inventoryVo = obj.toBean(InventoryVo.class);
            return inventoryVo.getCustomerId() + "-" + inventoryVo.getGoodsName();
        }));
    }

}
